package com.Humanities.auth.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.token.AuthorizationServerTokenServices;
import org.springframework.security.oauth2.provider.token.DefaultTokenServices;

import javax.annotation.Resource;

/**
 * @description 认证服务器配置
 * @description OAuth2认证服务器配置类
 *  * 该类通过继承 AuthorizationServerConfigurerAdapter 并添加 @EnableAuthorizationServer 注解，
 *  * 用于配置和启用一个 OAuth2 授权服务器，实现对客户端的认证、令牌的发放和验证等功能。
 *  *
 *  * 主要功能：
 *  * 1. 配置支持的客户端信息（如 client_id、secret、授权类型等）
 *  * 2. 配置令牌的生成、存储和服务（使用自定义 TokenServices）
 *  * 3. 配置认证管理器，与 Spring Security 集成
 *  * 4. 设置令牌端点的安全策略（如 token_key、check_token 的访问权限等）
 * @author Mr.M
 * @date 2022/9/26 22:25
 * @version 1.0
 */
 @Configuration
 @EnableAuthorizationServer
 public class AuthorizationServer extends AuthorizationServerConfigurerAdapter {
 // 自定义令牌服务，用于生成和管理令牌
  @Resource(name="authorizationServerTokenServicesCustom")
  private AuthorizationServerTokenServices authorizationServerTokenServices;
 // Spring Security 的认证管理器
 @Autowired
 private AuthenticationManager authenticationManager;

  //客户端详情服务
  @Override
  public void configure(ClientDetailsServiceConfigurer clients)
          throws Exception {

   //使用了内存方式配置客户端
   clients.inMemory()// 使用in-memory存储
                .withClient("XcWebApp")// client_id
//                .secret("XcWebApp")//客户端密钥
                .secret(new BCryptPasswordEncoder().encode("XcWebApp"))// 客户端密钥（加密）
                .resourceIds("xuecheng-plus")//资源列表
                .authorizedGrantTypes("authorization_code", "password","client_credentials","implicit","refresh_token")// 该client允许的授权类型authorization_code,password,refresh_token,implicit,client_credentials
                .scopes("all")// 允许的授权范围
                .autoApprove(false)//false跳转到授权页面
                //客户端接收授权码的重定向地址
                .redirectUris("http://www.51xuecheng.cn");
  }


  //令牌端点的访问配置
  @Override
  public void configure(AuthorizationServerEndpointsConfigurer endpoints) {
   //. 令牌端点配置（configure(AuthorizationServerEndpointsConfigurer endpoints)）
   //绑定认证管理器与令牌服务，并允许使用 POST 方式申请 token
   /**
    * 配置令牌端点的属性
    * 绑定认证管理器、令牌服务，支持 POST 请求获取 token
    */
   endpoints
           .authenticationManager(authenticationManager)//认证管理器
           .tokenServices(authorizationServerTokenServices)//令牌管理服务
           .allowedTokenEndpointRequestMethods(HttpMethod.POST);
  }

 /**
  * 配置令牌端点 (/oauth/token) 的安全访问策略
  * - 允许所有人访问 /oauth/token_key 和 /oauth/check_token
  * - 允许客户端使用表单方式提交认证信息
  */
  @Override
  public void configure(AuthorizationServerSecurityConfigurer security){
   security
           .tokenKeyAccess("permitAll()")                    //oauth/token_key是公开
           .checkTokenAccess("permitAll()")                  //oauth/check_token公开
           .allowFormAuthenticationForClients();			//表单认证（申请令牌）
  }
 }
